//
//  NSString+Common.m
//  ZhaoQiPei
//
//  Created by 找汽配ios开发 on 16/1/26.
//  Copyright © 2016年 祥运. All rights reserved.
//

#import "NSString+XY.h"

@implementation NSString (XY)

- (BOOL)isMobileNumber {
    if (self.length != 11) {
        return NO;
    }
    // 移动号段正则表达式
    NSString * CM_NUM = @"^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
    // 联通号段正则表达式
    NSString * CU_NUM = @"^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";
    // 电信号段正则表达式
    NSString * CT_NUM = @"^((133)|(153)|(17[3,7])|(18[0,1,9]))\\d{8}$";
    NSPredicate * pred_1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM_NUM];
    if ([pred_1 evaluateWithObject:self]) {
        return YES;
    }
    NSPredicate * pred_2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU_NUM];
    if ([pred_2 evaluateWithObject:self]) {
        return YES;
    }
    NSPredicate * pred_3 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT_NUM];
    if ([pred_3 evaluateWithObject:self]) {
        return YES;
    }
    return NO;
}

- (BOOL)isIDNumber {
    if (self.length == 18) {
        NSArray * array_1 = @[@7, @9, @10, @5, @8, @4, @2, @1, @6, @3, @7, @9, @10, @5, @8, @4, @2, @1];
        NSArray * array_2 = @[@"1", @"0", @"X", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2"];
        NSMutableArray * ID_array = [[NSMutableArray alloc] initWithCapacity:18];
        for (int i = 0; i < self.length; i++) {
            [ID_array addObject:[self substringWithRange:NSMakeRange(i, 1)]];
        }
        NSInteger sum = 0;
        for (int i = 0; i < 17; i++) {
            sum = sum + [array_1[i] integerValue] * [ID_array[i] integerValue];
        }
        NSString * lastString = ID_array[17];
        NSString * string = array_2[sum % 11];
        
        return [lastString isEqualToString:string];
    }
    else {
        return NO;
    }
}

- (BOOL)isBankCardNumber {
    // 纯数字，15－20位数字之间
    NSString * regex = @"^\\d{15,20}$";
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    if (![predicate evaluateWithObject:self]) {
        return NO;
    }

    NSString * lastNum = [self substringFromIndex:self.length - 1];     // 取出最后一位
    NSString * forwardNum = [self substringToIndex:self.length - 1];    // 前15或18位
    
    NSMutableArray * forwardArr = [NSMutableArray arrayWithCapacity:forwardNum.length];
    for (NSInteger i = 0; i < forwardNum.length; i++) {
        NSString * subStr = [forwardNum substringWithRange:NSMakeRange(i, 1)];
        [forwardArr addObject:subStr];
    }
    
    NSMutableArray * forwardDescArr = [[NSMutableArray alloc] initWithCapacity:forwardArr.count];
    for (NSInteger i = forwardArr.count - 1; i >= 0; i--) { // 前15位或者前18位倒序存进数组
        [forwardDescArr addObject:forwardArr[i]];
    }
    
    NSMutableArray * arrOddNum = [[NSMutableArray alloc] initWithCapacity:0];   // 奇数位*2的积 < 9
    NSMutableArray * arrOddNum2 = [[NSMutableArray alloc] initWithCapacity:0];  // 奇数位*2的积 > 9
    NSMutableArray * arrEvenNum = [[NSMutableArray alloc] initWithCapacity:0];  // 偶数位数组
    
    for (int i = 0; i < forwardDescArr.count; i++) {
        NSInteger num = [forwardDescArr[i] intValue];
        if (i % 2) {    // 偶数位
            [arrEvenNum addObject:[NSNumber numberWithInteger:num]];
        } else {        // 奇数位
            if (num * 2 < 9) {
                [arrOddNum addObject:[NSNumber numberWithInteger:num * 2]];
            } else {
                NSInteger decadeNum = (num * 2) / 10;
                NSInteger unitNum = (num * 2) % 10;
                [arrOddNum2 addObject:[NSNumber numberWithInteger:unitNum]];
                [arrOddNum2 addObject:[NSNumber numberWithInteger:decadeNum]];
            }
        }
    }

    __block NSInteger sumOddNumTotal = 0;
    [arrOddNum enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
        sumOddNumTotal += [obj integerValue];
    }];

    __block NSInteger sumOddNum2Total = 0;
    [arrOddNum2 enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
        sumOddNum2Total += [obj integerValue];
    }];

    __block NSInteger sumEvenNumTotal = 0;
    [arrEvenNum enumerateObjectsUsingBlock:^(NSNumber * obj, NSUInteger idx, BOOL *stop) {
        sumEvenNumTotal += [obj integerValue];
    }];

    NSInteger lastNumber = [lastNum integerValue];
    NSInteger luhmTotal = lastNumber + sumEvenNumTotal + sumOddNum2Total + sumOddNumTotal;
    return (luhmTotal % 10 == 0) ? YES : NO;
}

- (BOOL)isPostcode {
    NSString * regex = @"[1-9]\\d{5}(?!\\d)";
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [predicate evaluateWithObject:self];
}

- (BOOL)isPrice {
    NSString * regex = @"^(0|[1-9][0-9]{0,9})(\\.[0-9]{0,2})?$";
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [predicate evaluateWithObject:self];
}

- (BOOL)isLoginPassword {
    NSString * regex = @"^[a-zA-Z0-9\\-/:;\\(\\)\\$&@\"\\.,\\?!'\\[\\]\\{\\}#%\\^\\*\\+=_\\\\\\|~<>]{6,18}$";
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [predicate evaluateWithObject:self];
}

- (BOOL)isPayPassword {
//    NSString * regex = @"^[a-zA-Z0-9]{6,18}$";
    NSString * regex = @"^[a-zA-Z0-9\\-/:;\\(\\)\\$&@\"\\.,\\?!'\\[\\]\\{\\}#%\\^\\*\\+=_\\\\\\|~<>]{6,18}$";
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [predicate evaluateWithObject:self];
}

- (NSString *)unicodeString {
    NSUInteger length = [self length];
    NSMutableString * s = [NSMutableString string];
    for (int i = 0; i < length; i++) {
        unichar _char = [self characterAtIndex:i];
        //判断是否为英文和数字
        if (_char <= '9' && _char >= '0')
        {
            [s appendFormat:@"%@", [self substringWithRange:NSMakeRange(i, 1)]];
        }
        else if(_char >= 'a' && _char <= 'z')
        {
            [s appendFormat:@"%@", [self substringWithRange:NSMakeRange(i, 1)]];
        }
        else if(_char >= 'A' && _char <= 'Z')
        {
            [s appendFormat:@"%@", [self substringWithRange:NSMakeRange(i, 1)]];
        }
        else
        {
            [s appendFormat:@"\\u%x", [self characterAtIndex:i]];
        }
    }
    return s;
}

- (NSString *)urlQueryEncode {
    return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)self, NULL, (__bridge CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8);
}

- (NSString *)stringShouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSMutableString * mString = [NSMutableString stringWithString:self];
    [mString deleteCharactersInRange:range];
    [mString insertString:string atIndex:range.location];
    return [mString copy];
}

- (NSString *)URLDecode {
    return [self stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}

- (NSString *)URLEncode {
    NSString *encUrl = [self stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSUInteger len = [encUrl length];
    const char *c;
    c = [encUrl UTF8String];
    NSString *ret = @"";
    for(int i = 0; i < len; i++) {
        switch (*c) {
            case '~':
                ret = [ret stringByAppendingString:@"%7E"];
                break;
            case '/':
                ret = [ret stringByAppendingString:@"%2F"];
                break;
            case '\'':
                ret = [ret stringByAppendingString:@"%27"];
                break;
            case ';':
                ret = [ret stringByAppendingString:@"%3B"];
                break;
            case '?':
                ret = [ret stringByAppendingString:@"%3F"];
                break;
            case ':':
                ret = [ret stringByAppendingString:@"%3A"];
                break;
            case '@':
                ret = [ret stringByAppendingString:@"%40"];
                break;
            case '&':
                ret = [ret stringByAppendingString:@"%26"];
                break;
            case '=':
                ret = [ret stringByAppendingString:@"%3D"];
                break;
            case '+':
                ret = [ret stringByAppendingString:@"%2B"];
                break;
            case '$':
                ret = [ret stringByAppendingString:@"%24"];
                break;
            case ',':
                ret = [ret stringByAppendingString:@"%2C"];
                break;
            case '[':
                ret = [ret stringByAppendingString:@"%5B"];
                break;
            case ']':
                ret = [ret stringByAppendingString:@"%5D"];
                break;
            case '#':
                ret = [ret stringByAppendingString:@"%23"];
                break;
            case '!':
                ret = [ret stringByAppendingString:@"%21"];
                break;
            case '(':
                ret = [ret stringByAppendingString:@"%28"];
                break;
            case ')':
                ret = [ret stringByAppendingString:@"%29"];
                break;
            case '*':
                ret = [ret stringByAppendingString:@"%2A"];
                break;
            default:
                ret = [ret stringByAppendingFormat:@"%c", *c];
        }
        c++;
    }
    return ret;
}

@end
